//
//  HelloWorldLayer.m
//  ExampleAnimatingSprite
//
//  Created by admin on 3/16/12.
//  Copyright __MyCompanyName__ 2012. All rights reserved.
//


// Import the interfaces
#import "HelloWorldLayer.h"


// HelloWorldLayer implementation
@implementation HelloWorldLayer
enum {
	TAG_CASTLE = 0,
	TAG_LIGHTNING_BOLT = 1,
	TAG_BATS = 2
};
#define MAX_NO_BAT      10
//Bat animation types
enum {
	BAT_FLYING_UP = 0,
	BAT_GLIDING_DOWN = 1
};


+(CCScene *) scene
{
	// 'scene' is an autorelease object.
	CCScene *scene = [CCScene node];
	
	// 'layer' is an autorelease object.
	HelloWorldLayer *layer = [HelloWorldLayer node];
	
	// add layer as a child to scene
	[scene addChild: layer];
	
	// return the scene
	return scene;
}
- (void)spriteMoveFinished:(id)sprite
{
    [sprite removeFromParentAndCleanup:YES];
    NSLog(@">>>>>>>>>>>>>");
}
/* Create a glow effect */
-(void) glowAt:(CGPoint)position withScale:(CGSize)size withColor:(ccColor3B)color withRotation:(float)rotation withSprite:(CCSprite*)sprite {
	CCSprite *glowSprite = [CCSprite spriteWithFile:@"fire.png"];
	[glowSprite setColor:color];
	[glowSprite setPosition:position];
	[glowSprite setRotation:rotation];
	[glowSprite setBlendFunc: (ccBlendFunc) { GL_ONE, GL_ONE }];
	[glowSprite runAction: [CCRepeatForever actionWithAction:
                            [CCSequence actions:[CCScaleTo actionWithDuration:0.5 scaleX:size.width scaleY:size.height], 
                             [CCScaleTo actionWithDuration:0.5 scaleX:size.width*0.75 scaleY:size.height*0.75], nil] ] ];	
	[glowSprite runAction: [CCRepeatForever actionWithAction:
                            [CCSequence actions:[CCFadeTo actionWithDuration:0.5 opacity:255], 
                             [CCFadeTo actionWithDuration:0.5 opacity:10],
                             [CCCallFuncN actionWithTarget:self selector:@selector(spriteMoveFinished:)],nil ]]];	
  
	[self addChild:glowSprite];
    [sprite removeFromParentAndCleanup:YES];
}

-(float)makeBatFlyUp:(SimpleObject*)bat{
    CCSpriteFrameCache* cache = [CCSpriteFrameCache sharedSpriteFrameCache] ;
    
    float delay = (float)(arc4random() %5 + 5) / 80.0;
    CCAnimation* animation = [[CCAnimation alloc] init];
    [animation setDelay:delay];

    
    int num = arc4random() % 4 + 1;
    for (int i = 1; i < 4; i++) {
        [animation addFrame:[cache spriteFrameByName:[NSString  stringWithFormat:@"simple_bat_0%i.png",num]]];
        num = (num + i) % 4 + 1;
    }
//    [bat stopAllActions];
    [bat runAction:[CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:animation]]];
  [bat runAction:[CCRepeatForever actionWithAction:[CCScaleTo actionWithDuration:1.0f scale:bat.scale]]];
    
    bat.animationType = BAT_FLYING_UP;
    
    return delay;
}

-(void)makeBatGlideDown:(SimpleObject*)bat {
	CCSpriteFrameCache * cache = [CCSpriteFrameCache sharedSpriteFrameCache];
    
	//Apply a simple single frame gliding animation.
    CCAnimation* animation = [[CCAnimation alloc] init];
    [animation setDelay:100.0f];
	[animation addFrame:[cache spriteFrameByName:@"simple_bat_01.png"]];
	
	//Stop any running animations and apply this one.
//	[bat stopAllActions];
	[bat runAction:[CCRepeatForever actionWithAction: [CCAnimate actionWithAnimation:animation]]];
	[bat runAction:[CCRepeatForever actionWithAction:[CCScaleTo actionWithDuration:1.0f scale:bat.scale]]];
	//Keep track of which animation is running.
	bat.animationType = BAT_GLIDING_DOWN;
}

- (void)addBat
{
    
    CCSpriteBatchNode* batch = [CCSpriteBatchNode batchNodeWithFile:@"simple_bat.png" capacity:MAX_NO_BAT];
    [self addChild:batch z:2 tag:TAG_BATS];
    
    for(int i = 0; i < MAX_NO_BAT; i++)
    {
        SimpleObject* bat = [SimpleObject spriteWithBatchNode:batch rect:CGRectMake(0.0, 0.0, 48.0, 48.0)];
        [bat setLevel:1];
        [bat setScale:1.0];        
        
        [batch addChild:bat];
        [bat setPosition:ccp(arc4random()%400+40, arc4random()%150+150)];
        
        float flappingSpeed = [self makeBatFlyUp:bat];
        bat.velocity = ccp((arc4random()%1000)/500 + 0.2f, 0.1f/flappingSpeed);
        //Add a pointer to this bat object to the NSMutableArray
		[_bats addObject:[NSValue valueWithPointer:bat]];
        
		[bat retain];
        
        if(bat.velocity.x > 0){
			bat.flipX = YES;
		}

    }
}

- (void)addBackground
{
    //Add castle background
	CCSprite *castle = [CCSprite spriteWithFile:@"dracula_castle.jpg"];
	[castle setPosition:ccp(240,160)];
	[self addChild: castle z:0 tag:TAG_CASTLE];
    
    //Add a lightning bolt
	_lightningBolt = [CCSprite spriteWithFile:@"lightning_bolt.png"];
	[_lightningBolt setPosition:ccp(240,160)];
	[_lightningBolt setOpacity:64];
	[_lightningBolt retain];
    
	//Add a sprite to make it light up other areas.
	_lightningGlow = [CCSprite spriteWithFile:@"lightning_glow.png"];
	[_lightningGlow setColor:ccc3(255,255,0)];
	[_lightningGlow setPosition:ccp(240,160)];
	[_lightningGlow setOpacity:100];
	[_lightningGlow setBlendFunc: (ccBlendFunc) { GL_ONE, GL_ONE }];
	[_lightningBolt addChild:_lightningGlow];
	
	//Set a counter for lightning duration randomization
	lightningRemoveCount = 0;

}

- (void)collisionDetection:(ccTime)delta {
    
    NSMutableArray* batToUpLevel = [[NSMutableArray alloc] init];
    NSMutableArray* batToDownLevel = [[NSMutableArray alloc] init];
    
    for (int i = 0;i < [_bats count] -1 ;i++) {
        SimpleObject* bat = [(id)[_bats objectAtIndex:i] pointerValue];  
        
        CGRect targetRect = CGRectMake(bat.position.x - bat.contentSize.width / 2, 
                                       bat.position.y - bat.contentSize.height / 2, 
                                       bat.contentSize.width, 
                                       bat.contentSize.height);
        for(int j = i +1; j< [_bats count]; j++)
        {       
            SimpleObject* bat2 = [(id)[_bats objectAtIndex:j] pointerValue];  
            
            CGRect projectileRect = CGRectMake(bat2.position.x - bat2.contentSize.width / 2, 
                                               bat2.position.y - bat2.contentSize.height / 2, 
                                               bat2.contentSize.width, 
                                               bat2.contentSize.height);
            
            if (CGRectIntersectsRect(projectileRect, targetRect)) {		
                if (bat.animationType < bat2.animationType) {
                    [batToUpLevel addObject:bat];
                    [batToDownLevel addObject:bat2];
                }
//                }else if (bat.animationType > bat2.animationType){
//                    [batToUpLevel addObject:bat2];
//                    [batToDownLevel addObject:bat];
//                }
            }
        }
    }
    for(SimpleObject* batUp in batToUpLevel)
    {
        batUp.scale += 0.5;
        if(batUp.scale > 2)
        {
            batUp.scale = 2;
        }        
    }
    [batToUpLevel release];
    batToUpLevel = nil;


    for(SimpleObject* batDown in batToDownLevel)
    {
       [self glowAt:batDown.position withScale:CGSizeMake(2.0, 2.0) withColor:ccc3(0,230,255) withRotation:0.0f withSprite:batDown];

        [_bats removeObject:(id)batDown];
       
    }
    [batToDownLevel release];
    batToDownLevel = nil;
}

- (void)update:(ccTime)delta 
{
    CGSize winSize = [[CCDirector sharedDirector] winSize];
    
    for (id key in _bats) {
        SimpleObject* bat = [key pointerValue];
        
        //Make sure bats don't fly off the screen
		if(bat.position.x > winSize.width){
			bat.velocity = ccp(-bat.velocity.x, bat.velocity.y);
			bat.flipX = NO;
		}else if(bat.position.x < 0){
			bat.velocity = ccp(-bat.velocity.x, bat.velocity.y);
			bat.flipX = YES;
		}else if(bat.position.y > winSize.height){
			bat.velocity = ccp(bat.velocity.x, -bat.velocity.y);
			[self makeBatGlideDown:bat];
		}else if(bat.position.y < 0){
			bat.velocity = ccp(bat.velocity.x, -bat.velocity.y);
			[self makeBatFlyUp:bat];
		}
        
        //Update bat position based on direction
		bat.position = ccp(bat.position.x + bat.velocity.x, bat.position.y + bat.velocity.y);

    }
    //Randomly make lightning strike
	if(arc4random()%70 == 7){
		if(lightningRemoveCount < 0){
			[self addChild:_lightningBolt z:1 tag:TAG_LIGHTNING_BOLT];
			lightningRemoveCount = arc4random()%5+5;
		}
	}
	
	//Count down
	lightningRemoveCount -= 1;
    //Clean up any old lightning bolts
	if(lightningRemoveCount == 0){
		[self removeChildByTag:TAG_LIGHTNING_BOLT cleanup:NO];
	}

}
-(void)stopMovie {
	//We do not stop the movie if it is already stopped.
	MPMoviePlaybackState state = moviePlayer.playbackState;
	if(state == MPMoviePlaybackStateStopped) {
		NSLog(@"Movie is already stopped.");
		return;
	}
	
	//Since playback has finished we remove the observer.
	[[NSNotificationCenter defaultCenter] removeObserver:self
                                                    name:MPMoviePlayerPlaybackDidFinishNotification
                                                  object:moviePlayer];
    
	//If the moviePlayer.view was added to the openGL view, it needs to be removed.
	if ([moviePlayer respondsToSelector:@selector(setFullscreen:animated:)]) {
		[moviePlayer.view removeFromSuperview];
	}
}
-(void)playMovie {
	//We do not play the movie if it is already playing.
	MPMoviePlaybackState state = moviePlayer.playbackState;
	if(state == MPMoviePlaybackStatePlaying) {
		NSLog(@"Movie is already playing.");
		return;
	}
	
	[moviePlayer play];
}

-(void)moviePlayBackDidFinish:(NSNotification*)notification {
	//If playback is finished we stop the movie.
	[self stopMovie];
}

- (void)playVideo
{
    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"example_vid" ofType:@"mov"]];
	
	//Create a MPMoviePlayerController object
	moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:url];
    
	//Register to receive a notification when the movie has finished playing.
	[[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(moviePlayBackDidFinish:)
                                                 name:MPMoviePlayerPlaybackDidFinishNotification
                                               object:moviePlayer];
    
	//Set the movie's control style and whether or not it should automatically play.
	if ([moviePlayer respondsToSelector:@selector(setFullscreen:animated:)]) {
		//Use the new 3.2 style API.
		moviePlayer.controlStyle = MPMovieControlStyleNone;
		moviePlayer.shouldAutoplay = YES;
        
		CGSize winSize = [[CCDirector sharedDirector] winSize];
		moviePlayer.view.frame = CGRectMake(45, 50, winSize.width-90, winSize.height-100);
		[[[CCDirector sharedDirector] openGLView] addSubview:moviePlayer.view];
	} else {
		//Use the old 2.0 style API.
		[moviePlayer setMovieControlMode:MPMovieControlModeHidden];
		[self playMovie];
	}
}


- (void)addShapeLayer
{
    ShapePlayer *layer = [[ShapePlayer alloc] init];
    [layer setPosition:ccp(0,0)];
    [self addChild:layer z:2 tag:0];
}

- (void)addAnimationSprite
{
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"simple_bat.plist"];
    
    _bats = [[NSMutableArray alloc] init];
    
    [self addBackground];
    [self addBat];
    [self schedule:@selector(update:)];
    [self schedule:@selector(collisionDetection:)];

}

- (void) addGridEffect
{
    MyGridEffect *layer = [[MyGridEffect alloc] init];
    [layer runRecipe];
    [layer setPosition:ccp(0,0)];
    [self addChild:layer z:2 tag:0];
}

-(void) addParticleEffect
{
    MyParticleEffect *layer = [[MyParticleEffect alloc] init];
    [layer runRecipe];
    [layer setPosition:ccp(0,0)];
    [self addChild:layer z:2 tag:0];
}

- (void)addRenderTexturePolygon
{
    CGPoint vertexArr[] = { 
        ccp(0 ,0), 
        ccp(0,320), 
        ccp(480,320), 
        ccp(480,0), 
        ccp(0 ,0),};
	int numVerts = 4;
	
	NSMutableArray *vertices = [[[NSMutableArray alloc] init] autorelease];
	
	for(int i=0; i<numVerts; i++){
		[vertices addObject:[NSValue valueWithCGPoint:vertexArr[i]]];
	}
    
	//Note: Your texture MUST be a product of 2 for this to work.
	ccTexParams params = {GL_NEAREST,GL_NEAREST_MIPMAP_NEAREST,GL_REPEAT,GL_REPEAT};
	TexturedPolygon *texturedPoly = [TexturedPolygon createWithFile:@"bricks.jpg" withVertices:vertices];
	[texturedPoly.texture setTexParameters:&params];
	texturedPoly.position = ccp(0,0);
	
	[self addChild:texturedPoly z:1 tag:0];

}
// on "init" you need to initialize your instance

-(void)setBackground
{
    CGSize size = [[CCDirector sharedDirector] winSize];
	CCSprite *bg = [CCSprite spriteWithFile:@"blank.png"];
	bg.position = ccp(size.width/2,size.height/2);
	[bg setTextureRect:CGRectMake(0, 0, size.width, size.height)];
	bg.color = ccc3(100,100,100);
	[self addChild:bg z:0 tag:0];
}
-(id) init
{
	if( (self=[super init])) {
        [self setBackground];
	}  
//    [self addAnimationSprite];
//    [self playMovie];
//    [self addShapeLayer];
    
    
//    [self addGridEffect];
    
//    [self addParticleEffect];
    [self addRenderTexturePolygon];
	return self;
}



// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
    [_bats release];
    _bats = nil;
    
	[super dealloc];
}
@end
